package com.lifeverse.service;

import com.lifeverse.dto.LifeEntityRelationshipCreateDTO;
import com.lifeverse.dto.LifeEntityRelationshipDTO;
import com.lifeverse.dto.LifeEntityRelationshipUpdateDTO;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.LifeEntityRelationship;
import com.lifeverse.exception.BusinessException;
import com.lifeverse.repository.LifeEntityRelationshipRepository;
import com.lifeverse.repository.LifeEntityRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 生命体关系管理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LifeEntityRelationshipService {
    
    private final LifeEntityRelationshipRepository relationshipRepository;
    private final LifeEntityRepository lifeEntityRepository;
    
    /**
     * 创建生命体关系
     */
    @Transactional
    public LifeEntityRelationshipDTO createRelationship(LifeEntityRelationshipCreateDTO createDTO) {
        log.info("创建生命体关系: sourceId={}, targetId={}, type={}", 
                createDTO.getSourceEntityId(), createDTO.getTargetEntityId(), createDTO.getRelationshipType());
        
        // 验证源生命体和目标生命体存在
        LifeEntity sourceEntity = lifeEntityRepository.findById(createDTO.getSourceEntityId())
                .orElseThrow(() -> new BusinessException("源生命体不存在: " + createDTO.getSourceEntityId()));
        
        LifeEntity targetEntity = lifeEntityRepository.findById(createDTO.getTargetEntityId())
                .orElseThrow(() -> new BusinessException("目标生命体不存在: " + createDTO.getTargetEntityId()));
        
        // 检查是否已存在相同的关系
        Optional<LifeEntityRelationship> existingRelationship = 
                relationshipRepository.findBySourceEntityAndTargetEntity(sourceEntity, targetEntity);
        
        if (existingRelationship.isPresent()) {
            throw new BusinessException("生命体之间已存在关系");
        }
        
        // 创建关系实体
        LifeEntityRelationship relationship = new LifeEntityRelationship();
        relationship.setSourceEntity(sourceEntity);
        relationship.setTargetEntity(targetEntity);
        relationship.setRelationshipType(createDTO.getRelationshipType());
        relationship.setRelationshipStatus(LifeEntityRelationship.RelationshipStatus.ACTIVE);
        relationship.setRelationshipStrength(createDTO.getRelationshipStrength());
        relationship.setRelationshipQuality(createDTO.getRelationshipQuality());
        relationship.setTrustLevel(createDTO.getTrustLevel());
        relationship.setInteractionFrequency(createDTO.getInteractionFrequency());
        relationship.setDescription(createDTO.getDescription());
        relationship.setTags(createDTO.getTags());
        relationship.setAttributes(createDTO.getAttributes());
        relationship.setImpactScore(createDTO.getImpactScore());
        relationship.setIsBidirectional(createDTO.getIsBidirectional());
        relationship.setNetworkWeight(createDTO.getNetworkWeight());
        relationship.setEstablishedAt(LocalDateTime.now());
        relationship.setLastInteractionAt(LocalDateTime.now());
        
        LifeEntityRelationship savedRelationship = relationshipRepository.save(relationship);
        
        // 如果是双向关系，创建反向关系
        if (createDTO.getIsBidirectional()) {
            createReverseRelationship(savedRelationship);
        }
        
        log.info("成功创建生命体关系: id={}", savedRelationship.getId());
        return convertToDTO(savedRelationship);
    }
    
    /**
     * 创建反向关系
     */
    private void createReverseRelationship(LifeEntityRelationship originalRelationship) {
        LifeEntityRelationship reverseRelationship = new LifeEntityRelationship();
        reverseRelationship.setSourceEntity(originalRelationship.getTargetEntity());
        reverseRelationship.setTargetEntity(originalRelationship.getSourceEntity());
        reverseRelationship.setRelationshipType(originalRelationship.getRelationshipType());
        reverseRelationship.setRelationshipStatus(originalRelationship.getRelationshipStatus());
        reverseRelationship.setRelationshipStrength(originalRelationship.getRelationshipStrength());
        reverseRelationship.setRelationshipQuality(originalRelationship.getRelationshipQuality());
        reverseRelationship.setTrustLevel(originalRelationship.getTrustLevel());
        reverseRelationship.setInteractionFrequency(originalRelationship.getInteractionFrequency());
        reverseRelationship.setDescription(originalRelationship.getDescription());
        reverseRelationship.setTags(originalRelationship.getTags());
        reverseRelationship.setAttributes(originalRelationship.getAttributes());
        reverseRelationship.setImpactScore(originalRelationship.getImpactScore());
        reverseRelationship.setIsBidirectional(true);
        reverseRelationship.setNetworkWeight(originalRelationship.getNetworkWeight());
        reverseRelationship.setEstablishedAt(originalRelationship.getEstablishedAt());
        reverseRelationship.setLastInteractionAt(originalRelationship.getLastInteractionAt());
        
        relationshipRepository.save(reverseRelationship);
    }
    
    /**
     * 更新生命体关系
     */
    @Transactional
    public LifeEntityRelationshipDTO updateRelationship(Long relationshipId, LifeEntityRelationshipUpdateDTO updateDTO) {
        log.info("更新生命体关系: id={}", relationshipId);
        
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        // 更新字段
        if (updateDTO.getRelationshipType() != null) {
            relationship.setRelationshipType(updateDTO.getRelationshipType());
        }
        if (updateDTO.getRelationshipStatus() != null) {
            relationship.setRelationshipStatus(updateDTO.getRelationshipStatus());
        }
        if (updateDTO.getRelationshipStrength() != null) {
            relationship.setRelationshipStrength(updateDTO.getRelationshipStrength());
        }
        if (updateDTO.getRelationshipQuality() != null) {
            relationship.setRelationshipQuality(updateDTO.getRelationshipQuality());
        }
        if (updateDTO.getTrustLevel() != null) {
            relationship.setTrustLevel(updateDTO.getTrustLevel());
        }
        if (updateDTO.getInteractionFrequency() != null) {
            relationship.setInteractionFrequency(updateDTO.getInteractionFrequency());
        }
        if (updateDTO.getDescription() != null) {
            relationship.setDescription(updateDTO.getDescription());
        }
        if (updateDTO.getTags() != null) {
            relationship.setTags(updateDTO.getTags());
        }
        if (updateDTO.getAttributes() != null) {
            relationship.setAttributes(updateDTO.getAttributes());
        }
        if (updateDTO.getInteractionStats() != null) {
            relationship.setInteractionStats(updateDTO.getInteractionStats());
        }
        if (updateDTO.getImpactScore() != null) {
            relationship.setImpactScore(updateDTO.getImpactScore());
        }
        if (updateDTO.getIsBidirectional() != null) {
            relationship.setIsBidirectional(updateDTO.getIsBidirectional());
        }
        if (updateDTO.getNetworkWeight() != null) {
            relationship.setNetworkWeight(updateDTO.getNetworkWeight());
        }
        
        LifeEntityRelationship savedRelationship = relationshipRepository.save(relationship);
        
        log.info("成功更新生命体关系: id={}", savedRelationship.getId());
        return convertToDTO(savedRelationship);
    }
    
    /**
     * 删除生命体关系
     */
    @Transactional
    public void deleteRelationship(Long relationshipId) {
        log.info("删除生命体关系: id={}", relationshipId);
        
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        relationshipRepository.delete(relationship);
        
        log.info("成功删除生命体关系: id={}", relationshipId);
    }
    
    /**
     * 根据ID查询关系
     */
    public LifeEntityRelationshipDTO getRelationshipById(Long relationshipId) {
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        return convertToDTO(relationship);
    }
    
    /**
     * 查询生命体的所有关系
     */
    public List<LifeEntityRelationshipDTO> getRelationshipsByEntity(Long entityId) {
        LifeEntity entity = lifeEntityRepository.findById(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        List<LifeEntityRelationship> relationships = relationshipRepository.findAllRelationshipsByEntity(entity);
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 查询生命体的活跃关系
     */
    public List<LifeEntityRelationshipDTO> getActiveRelationshipsByEntity(Long entityId) {
        LifeEntity entity = lifeEntityRepository.findById(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        List<LifeEntityRelationship> relationships = relationshipRepository.findActiveRelationshipsByEntity(entity);
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据关系类型查询关系
     */
    public List<LifeEntityRelationshipDTO> getRelationshipsByType(LifeEntityRelationship.RelationshipType type) {
        List<LifeEntityRelationship> relationships = relationshipRepository.findByRelationshipType(type);
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 查询强关系
     */
    public List<LifeEntityRelationshipDTO> getStrongRelationships() {
        List<LifeEntityRelationship> relationships = relationshipRepository.findStrongRelationships();
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 查询高信任度关系
     */
    public List<LifeEntityRelationshipDTO> getHighTrustRelationships() {
        List<LifeEntityRelationship> relationships = relationshipRepository.findHighTrustRelationships();
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 分页查询关系
     */
    public Page<LifeEntityRelationshipDTO> getRelationshipsByStatus(
            LifeEntityRelationship.RelationshipStatus status, Pageable pageable) {
        Page<LifeEntityRelationship> relationshipPage = relationshipRepository.findByRelationshipStatus(status, pageable);
        
        List<LifeEntityRelationshipDTO> dtoList = relationshipPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        return new PageImpl<>(dtoList, pageable, relationshipPage.getTotalElements());
    }
    
    /**
     * 加强关系
     */
    @Transactional
    public LifeEntityRelationshipDTO strengthenRelationship(Long relationshipId, BigDecimal amount) {
        log.info("加强关系: id={}, amount={}", relationshipId, amount);
        
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        relationship.strengthenRelationship(amount);
        LifeEntityRelationship savedRelationship = relationshipRepository.save(relationship);
        
        log.info("成功加强关系: id={}, newStrength={}", relationshipId, savedRelationship.getRelationshipStrength());
        return convertToDTO(savedRelationship);
    }
    
    /**
     * 减弱关系
     */
    @Transactional
    public LifeEntityRelationshipDTO weakenRelationship(Long relationshipId, BigDecimal amount) {
        log.info("减弱关系: id={}, amount={}", relationshipId, amount);
        
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        relationship.weakenRelationship(amount);
        LifeEntityRelationship savedRelationship = relationshipRepository.save(relationship);
        
        log.info("成功减弱关系: id={}, newStrength={}", relationshipId, savedRelationship.getRelationshipStrength());
        return convertToDTO(savedRelationship);
    }
    
    /**
     * 终止关系
     */
    @Transactional
    public LifeEntityRelationshipDTO terminateRelationship(Long relationshipId) {
        log.info("终止关系: id={}", relationshipId);
        
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        relationship.terminateRelationship();
        LifeEntityRelationship savedRelationship = relationshipRepository.save(relationship);
        
        log.info("成功终止关系: id={}", relationshipId);
        return convertToDTO(savedRelationship);
    }
    
    /**
     * 更新互动时间
     */
    @Transactional
    public void updateInteractionTime(Long relationshipId) {
        LifeEntityRelationship relationship = relationshipRepository.findById(relationshipId)
                .orElseThrow(() -> new BusinessException("关系不存在: " + relationshipId));
        
        relationship.updateLastInteractionTime();
        relationshipRepository.save(relationship);
    }
    
    /**
     * 查找需要维护的关系
     */
    public List<LifeEntityRelationshipDTO> getRelationshipsNeedingMaintenance() {
        List<LifeEntityRelationship> relationships = relationshipRepository.findRelationshipsNeedingMaintenance();
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 查找长时间未互动的关系
     */
    public List<LifeEntityRelationshipDTO> getInactiveRelationships(int daysThreshold) {
        LocalDateTime threshold = LocalDateTime.now().minusDays(daysThreshold);
        List<LifeEntityRelationship> relationships = relationshipRepository.findInactiveRelationships(threshold);
        
        return relationships.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    /**
     * 统计生命体的关系数量
     */
    public long countRelationshipsByEntity(Long entityId) {
        LifeEntity entity = lifeEntityRepository.findById(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        return relationshipRepository.countRelationshipsByEntity(entity);
    }
    
    /**
     * 统计某种类型的关系数量
     */
    public long countRelationshipsByType(LifeEntityRelationship.RelationshipType type) {
        return relationshipRepository.countByRelationshipType(type);
    }
    
    /**
     * 转换为DTO
     */
    private LifeEntityRelationshipDTO convertToDTO(LifeEntityRelationship relationship) {
        LifeEntityRelationshipDTO dto = new LifeEntityRelationshipDTO();
        BeanUtils.copyProperties(relationship, dto);
        
        // 设置生命体信息
        dto.setSourceEntityId(relationship.getSourceEntity().getId());
        dto.setSourceEntityName(relationship.getSourceEntity().getName());
        dto.setTargetEntityId(relationship.getTargetEntity().getId());
        dto.setTargetEntityName(relationship.getTargetEntity().getName());
        
        return dto;
    }
}